package com.util_code.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.util_code.dagger.help.PreferencesHelper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.UUID;

public class DeviceUuid {

    @SuppressLint("MissingPermission")
    public static String getDeviceId(Context context) {
        String uniqueDeviceId = PreferencesHelper.get("deviceuuid", "");
        if (!StringUtils.isEmpty(uniqueDeviceId)) {
            return uniqueDeviceId;
        }
        try {
            //IMEI : (International Mobile Equipment Identity)是国际移动设备身份码的缩写
            //MEID : (Mobile Equipment IDentifier)是全球唯一的56bit CDMA制式移动终端标识号
            uniqueDeviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
                    .getDeviceId();
        } catch (Exception e) {
            //非手机设备无
            //权限问题未授权无
            // notAuth premission
        }

        if (!TextUtils.isEmpty(uniqueDeviceId) && !uniqueDeviceId.startsWith("000000")) {
            return uniqueDeviceId;
        } else {
            //硬件序列,没有电话功能的设备会提供,某些手机可能进行提供
            String SimSerialNumber = null;
            try {
                SimSerialNumber = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
                        .getSimSerialNumber();
            } catch (Exception e) {
                //权限问题未授权无
                // notAuth premission
            }
            if (!TextUtils.isEmpty(SimSerialNumber)) {
                uniqueDeviceId = SimSerialNumber;
            } else {
                //ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数，当设备被wipe后该数重置
                //在主流厂商生产的设备上，有一个很经常的bug，就是每个设备都会产生相同的ANDROID_ID：9774d56d682e549c
                String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
                if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
                    uniqueDeviceId = androidId;
                } else {
                    uniqueDeviceId = new Installation().id(context);
                }
            }
        }

        return uniqueDeviceId;
    }

    /**
     * 这种方式是通过在程序安装后第一次运行后生成一个ID实现的但该方式跟设备唯一标识不一样，
     * 不同的应用程序会产生不同的ID，同一个程序重新安装也会不同。所以这不是设备的唯一ID，
     * 但是可以保证每个用户的ID是不同的。因此经常用来标识在某个应用中的唯一
     * ID（即Installtion ID），或者跟踪应用的安装数量。
     */
    static class Installation {
        private String sID = null;
        private final String INSTALLATION = "INSTALLATION";

        public synchronized String id(Context context) {
            if (sID == null) {
                File installation = new File(context.getFilesDir(), INSTALLATION);
                try {
                    if (!installation.exists()) {
                        writeInstallationFile(installation);
                    }
                    sID = readInstallationFile(installation);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return sID;
        }

        private String readInstallationFile(File installation) throws IOException {
            RandomAccessFile f = new RandomAccessFile(installation, "r");
            byte[] bytes = new byte[(int) f.length()];
            f.readFully(bytes);
            f.close();
            return new String(bytes);
        }

        private void writeInstallationFile(File installation) throws IOException {
            FileOutputStream out = new FileOutputStream(installation);
            String id = UUID.randomUUID().toString();
            out.write(id.getBytes());
            out.close();
        }
    }

}
